package com.stu.design.strategy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class PrintStrateFactory implements StrategyFactorty,InitializingBean,ApplicationContextAware{

    private ApplicationContext applicationContext;

    private Map<String,StrategyService>  serviceMap = new ConcurrentHashMap<>();

    @Override
    public StrategyService getHandler(String type) throws Exception{
        StrategyService strategyService = serviceMap.get(type);
        if (ObjectUtils.isEmpty(strategyService)){
            throw new Exception("StrategyService must be implements class.");
        }
        return strategyService;
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        Map<String, StrategyService> beansOfType = applicationContext.getBeansOfType(StrategyService.class);

        for (Map.Entry<String,StrategyService> entry: beansOfType.entrySet()){
            HandlerType annotation = entry.getValue().getClass().getAnnotation(HandlerType.class);
            if (ObjectUtils.isEmpty(annotation)){
                throw new Exception("annotation is must  not be null");
            }
            if (!StringUtils.hasText(annotation.value())){
                throw new Exception("annotation's value must not be null");
            }
            serviceMap.put(annotation.value(),entry.getValue());
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
